/**
 * Copyright (c) 2018-2028, Chill Zhuang 庄骞 (smallchill@163.com).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.babble.user.service.impl;

import com.babble.user.conversion.UserConversionMapper;
import com.babble.user.dto.UserOrToUserDTO;
import com.babble.user.entity.User;
import com.babble.user.entity.UserInfo;
import com.babble.user.entity.UserOauth;
import com.babble.user.mapper.UserMapper;
import com.babble.user.service.IUserService;
import com.babble.user.vo.UserUpdVO;
import com.babble.user.vo.UserVO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springblade.common.enums.CodeMsg;
import org.springblade.common.exception.MsgException;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.secure.utils.SecureUtil;
import org.springblade.core.tool.utils.DigestUtil;
import org.springblade.core.tool.utils.Func;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 用户表 服务实现类
 *
 * @author Blade
 * @since 2021-11-07
 */
@Service("web-user-server")
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
	@Autowired
	UserConversionMapper userConversionMapper;

	/**
	 * 判断邮箱是否重复
	 *
	 * @param email 邮箱
	 * @return
	 */
	@Override
	public void isEmail(String email) throws MsgException {
		//判断传入的邮箱和账号是否重复
		User entity = lambdaQuery()
			.eq(User::getEmail, email)
			.eq(User::getLoadingValid, 1)
			.one();
		User user = lambdaQuery().eq(User::getId, SecureUtil.getUser().getUserId()).eq(User::getEmail, email).one();
		if (entity != null) {
			throw new MsgException(CodeMsg.USER_EMAIL_OTHERS_IS_V.getCode(), CodeMsg.USER_EMAIL_OTHERS_IS_V.getMsg());
		}
		if (user == null) {
			throw new MsgException(CodeMsg.USER_EMAIL_AND_ONEEMAIL_IS_ARE.getCode(), CodeMsg.USER_EMAIL_AND_ONEEMAIL_IS_ARE.getMsg());
		}
	}

	/**
	 * 获取用户数据,分页
	 *
	 * @param page 查找页
	 * @param user 用户VO
	 * @return 用户集合
	 */
	@Override
	public IPage<UserVO> selectUserPage(IPage<UserVO> page, UserVO user) {
		return page.setRecords(baseMapper.selectUserPage(page, user));
	}

	/**
	 * 通过id获取用户
	 *
	 * @param userId 用户id
	 * @return 用户信息
	 */
	@Override
	public UserInfo userInfo(String userId) {
		return new UserInfo(this.getById(userId));
	}

	/**
	 * 通过账号密码获取信息
	 *
	 * @param username 账号
	 * @param password 密码
	 * @return
	 */
	@Override
	public UserInfo userInfo(String username, String password) {
		User user = lambdaQuery()
			.eq(User::getUsername, username).or().eq(User::getEmail,username)
			.eq(User::getStatus, 0)
			.one();
		if(user != null && password.equals(user.getPassword())){
			return new UserInfo(user, null, null, user.getUuid());
		}
		return new UserInfo();
	}

	/**
	 * 第三方获取用户信息 gitee
	 *
	 * @param userOauth 第三方传入的信息
	 * @return
	 */
	@Override
	@Transactional(rollbackFor = ServiceException.class)
	public UserInfo userInfo(UserOauth userOauth) {
		User user = lambdaQuery()
			.eq(User::getUuid, userOauth.getUuid())
			.eq(User::getStatus, 0)
			.one();
		if (user == null) {
			User EmailUser = lambdaQuery().eq(User::getEmail, userOauth.getEmail()).eq(User::getLoadingValid, 1).one();
			return getUserInfo(userOauth, EmailUser);
		}
		return new UserInfo(user, null, null, user.getUuid());
	}

	private UserInfo getUserInfo(UserOauth userOauth, User emailUser) {
		if (emailUser == null) {
			//新建用户，不创建用户名密码
			User newUser = new User()
				.setUuid(userOauth.getUuid())
				.setEmail(userOauth.getEmail())
				.setNickName(userOauth.getNickname())
				.setSource(userOauth.getSource())
				.setAvatar(userOauth.getAvatar())
				.setGender(userOauth.getGender())
				.setSummary(userOauth.getRemark())
				.setCommentStatus(true)
				.setStatus(0);
			this.save(newUser);
			return new UserInfo(newUser, null, null, userOauth.getUuid());
		} else {
			//已有用户，合并用户信息
			emailUser.setUuid(userOauth.getUuid());
			this.updateById(emailUser);

			return new UserInfo(emailUser, null, null, userOauth.getUuid());
		}
	}

	/**
	 * 用户注册
	 *
	 * @param user 用户信息
	 * @throws MsgException
	 */
	@Override
	public void registered(User user) throws MsgException {
		//判断传入的邮箱和账号是否重复
		User entity = lambdaQuery()
			.eq(User::getEmail, user.getEmail())
			.or().eq(User::getUsername, user.getUsername())
			.one();
		if (entity != null) {
			throw new MsgException(CodeMsg.USER_USERNAME_AND_EMAIL_IS_ARE.getCode(), CodeMsg.USER_USERNAME_AND_EMAIL_IS_ARE.getMsg());
		}
		user.setGender(0);
		user.setPassword(DigestUtil.encrypt(user.getPassword()));
		user.setAvatar("https://gitee.com/assets/no_portrait.png");
		user.setSource("平台注册");
		user.setCommentStatus(true);
		user.setStatus(0);
		user.setLoadingValid(false);
		this.save(user);
	}


	/**
	 * 邮箱认证
	 *
	 * @param userId 用户id
	 */
	@Override
	public void maillV(Long userId) {
		User entity = lambdaQuery()
			.eq(User::getId, userId)
			.one();
		entity.setLoadingValid(true);
		this.updateById(entity);
	}

	/**
	 * 修改用户信息
	 *
	 * @param user 用户信息
	 * @return
	 */
	@Override
	public User userUpd(User user) {
		user.setId(SecureUtil.getUser().getUserId().toString());
		this.updateById(user);
		return user;
	}
	/**
	 * 修改邮箱
	 *
	 * @param email 邮箱
	 * @throws MsgException
	 */
	@Override
	public void update(String email) throws MsgException {
		User entity = lambdaQuery()
			.eq(User::getId, SecureUtil.getUser().getUserId())
			.one();
		if (email.equals(entity.getEmail())) {
			throw new MsgException(CodeMsg.USER_EMAIL_AND_ONEEMAIL_IS_ARE.getCode(), CodeMsg.USER_EMAIL_AND_ONEEMAIL_IS_ARE.getMsg());
		}
		User user = lambdaQuery()
			.eq(User::getEmail, email)
			.one();
		if (user != null) {
			throw new MsgException(CodeMsg.USER_EMAIL_OTHERS_IS_V.getCode(), CodeMsg.USER_EMAIL_OTHERS_IS_V.getMsg());
		}
		entity.setLoadingValid(false);
		entity.setEmail(email);
		this.updateById(entity);
	}
	/**
	 * 判断用户是否需要认证
	 *
	 * @throws MsgException
	 */
	@Override
	public void isBind() throws MsgException {
		BladeUser user = SecureUtil.getUser();
		if(user == null){
			throw new MsgException(CodeMsg.PLASE_LOGIN.getCode(), CodeMsg.PLASE_LOGIN.getMsg());
		}
		User entity = lambdaQuery()
			.eq(User::getId, user.getUserId())
			.one();
		if (entity == null) {
			throw new MsgException(CodeMsg.PLASE_LOGIN.getCode(), CodeMsg.PLASE_LOGIN.getMsg());
		}
		if ("".equals(entity.getUsername()) || entity.getUsername() == null) {
			throw new MsgException(CodeMsg.USER_PLASE_V_USERNAME_AND_PASSWORD.getCode(), CodeMsg.USER_PLASE_V_USERNAME_AND_PASSWORD.getMsg());
		}
	}
	/**
	 * gitee绑定账户密码
	 *
	 * @param userName 账户
	 * @param password 密码
	 * @throws MsgException
	 */
	@Override
	public void bind(String userName, String password) throws MsgException {
		User entity = lambdaQuery()
			.eq(User::getUsername, userName)
			.one();
		if (entity != null) {
			throw new MsgException(CodeMsg.USER_V_USERNAME_IS_ARE.getCode(), CodeMsg.USER_V_USERNAME_IS_ARE.getMsg());
		}
		Long userId = SecureUtil.getUser().getUserId();
		User user = new User();
		user.setId(userId.toString());
		user.setUsername(userName);
		user.setPassword(DigestUtil.encrypt(password));
		this.updateById(user);
	}
	/**
	 * 修改用户信息
	 *
	 * @param user 用户修改userUpdVO数据
	 * @throws MsgException
	 */
	@Override
	public void updteInfo(UserUpdVO user) throws MsgException {
		String email = user.getEmail();
		if (!("".equals(email) || email == null)) {
			update(email);
		}
		User entity;
		entity = userConversionMapper.userToUserupd(user);
		entity.setId(SecureUtil.getUser().getUserId().toString());
		this.updateById(entity);
	}
	/**
	 * 修改密码
	 *
	 * @param oldPassword 老密码
	 * @param newPassword 新密码
	 * @throws MsgException
	 */
	@Override
	public void updatePwd(String oldPassword, String newPassword) throws MsgException {
		Long userId = SecureUtil.getUser().getUserId();
		User entity = lambdaQuery()
			.eq(User::getId, userId)
			.one();
		if (entity == null) {
			throw new MsgException(CodeMsg.PLASE_LOGIN.getCode(), CodeMsg.PLASE_LOGIN.getMsg());
		}
		String encrypt = DigestUtil.encrypt(oldPassword);
		if (!encrypt.equals(entity.getPassword())) {
			throw new MsgException(CodeMsg.USER_OLADE_PASSWORD_ERROR.getCode(), CodeMsg.USER_OLADE_PASSWORD_ERROR.getMsg());
		}
		entity.setPassword(DigestUtil.encrypt(newPassword));
		this.updateById(entity);
	}

	@Override
	public UserOrToUserDTO userInfoOrToUserinfo(String userId, String toUserId) {
		User user = this.getById(userId);
		UserOrToUserDTO.UserOrToUserDTOBuilder builder = UserOrToUserDTO.builder()
			.avatar(user.getAvatar())
			.nickName(user.getNickName());
		//第二个参数为空的话直接返回第一个数据
		if (Func.isNotEmpty(toUserId)) {
			User toUser = this.getById(toUserId);
			builder.toAvatar(toUser.getAvatar())
				.toNickName(toUser.getNickName());
		}
		return builder.build();
	}
}
